# 特征提取作业
import cv2.cv2 as cv2
import os 
import numpy as np


print(cv2.__version__)
# 棋盘图
# ======================================================================================================
chessboard_filename = os.path.abspath('第二次作业/chessboard1.jpg')
chessboard2_filename = os.path.abspath('第二次作业/chessboard2.jpg')
chessboard = cv2.imread(chessboard_filename)
chessboard2 = cv2.imread(chessboard2_filename)
# --------------------------------------------------------------------
# SURF特征匹配
minHessian = 5000
surf_detector = cv2.xfeatures2d.SURF_create(minHessian)
surf_detector.setUpright(True)

# 检测特征点
chessboard_keyPoint,chessboard_desc = surf_detector.detectAndCompute(chessboard,None)
chessboard2_keyPoint,chessboard2_desc = surf_detector.detectAndCompute(chessboard2,None)
img = cv2.drawKeypoints(chessboard,chessboard_keyPoint,chessboard)
img2 = cv2.drawKeypoints(chessboard2,chessboard2_keyPoint,chessboard2)
cv2.imshow('surf',img)
cv2.imshow('surf2',img2)

# 描述子匹配
chessboard_matcher = cv2.DescriptorMatcher_create('BruteForce')
matches = chessboard_matcher.match(chessboard_desc,chessboard2_desc)
img_matches = np.empty(chessboard2.shape)
img_matches1 = cv2.drawMatches(chessboard,chessboard_keyPoint,chessboard2
                                ,chessboard2_keyPoint,matches,img_matches)
cv2.imshow('chessboard_surf_matches',img_matches1)
print('chessboard_surf_keyPoint.size = ',len(chessboard_keyPoint))
print('chessboard2_surf_keyPoint.size = ',len(chessboard2_keyPoint))
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# FAST角点检测
chessboard = cv2.imread(chessboard_filename)
chessboard2 = cv2.imread(chessboard2_filename)
gray = cv2.cvtColor(chessboard,cv2.COLOR_BGR2GRAY)
# 如果用标准的棋盘图，FAST是检测不出来角点的
_,chessboard = cv2.threshold(gray,120,255,cv2.THRESH_OTSU)
cv2.imshow('gray',gray)
# 创建检测算子
fast_detector = cv2.FastFeatureDetector_create(30,nonmaxSuppression=True,type = cv2.FAST_FEATURE_DETECTOR_TYPE_9_16)

# 检测特征点
chessboard_keyPoint = fast_detector.detect(chessboard,None)
chessboard2_keyPoint = fast_detector.detect(chessboard2,None)
img = cv2.drawKeypoints(chessboard,chessboard_keyPoint,chessboard)
img2 = cv2.drawKeypoints(chessboard2,chessboard2_keyPoint,chessboard2)
cv2.imshow('fast',img)
cv2.imshow('fast2',img2)
print('chessboard_fast_keyPoint.size = ',len(chessboard_keyPoint))
print('chessboard2_fast_keyPoint.size = ',len(chessboard2_keyPoint))
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# SIFT特征描述
chessboard = cv2.imread(chessboard_filename)
chessboard2 = cv2.imread(chessboard2_filename)
# 创建检测算子
sift_detector = cv2.xfeatures2d.SIFT_create(nOctaveLayers=1,sigma=0.5)
# 计算特征点和描述符,FlannBased
chessboard_keyPoint,chessboard_desc = sift_detector.detectAndCompute(chessboard,None)
chessboard2_keyPoint,chessboard2_desc = sift_detector.detectAndCompute(chessboard2,None)
img = cv2.drawKeypoints(chessboard,chessboard_keyPoint,chessboard)
img2 = cv2.drawKeypoints(chessboard2,chessboard2_keyPoint,chessboard2)
cv2.imshow('sift',img)
cv2.imshow('sift2',img2)
# 匹配描述子FlannBased
chessboard_matcher = cv2.DescriptorMatcher_create('FlannBased')
matches = chessboard_matcher.match(chessboard_desc,chessboard2_desc)
img_matches = np.empty(chessboard2.shape)
img_matches1 = cv2.drawMatches(chessboard,chessboard_keyPoint,chessboard2,chessboard2_keyPoint,matches,img_matches)
cv2.imshow('chessboard_sift_matches',img_matches1)
print('chessboard_sift_keyPoint.size = ',len(chessboard_keyPoint))
print('chessboard2_sift_keyPoint.size = ',len(chessboard2_keyPoint))
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# ORB特征描述
chessboard = cv2.imread(chessboard_filename)
chessboard2 = cv2.imread(chessboard2_filename)
gray = cv2.cvtColor(chessboard,cv2.COLOR_BGR2GRAY)
# 如果用标准的棋盘图，FAST是检测不出来角点的
_,chessboard = cv2.threshold(gray,120,255,cv2.THRESH_OTSU)
# 创建ORB算子
orb_detector = cv2.ORB_create(200)
# 检测特征
chessboard_keyPoint,chessboard_desc = orb_detector.detectAndCompute(chessboard,None)
chessboard2_keyPoint,chessboard2_desc = orb_detector.detectAndCompute(chessboard2,None)
img = cv2.drawKeypoints(chessboard,chessboard_keyPoint,chessboard,color=[0,0,255])
img2 = cv2.drawKeypoints(chessboard2,chessboard2_keyPoint,chessboard2,color=[0,255,0])
cv2.imshow('orb',img)
cv2.imshow('orb2',img2)
# 匹配特征符
chessboard_matcher = cv2.DescriptorMatcher_create('BruteForce')
matches = chessboard_matcher.match(chessboard_desc,chessboard2_desc,)
img_matches = np.empty(chessboard2.shape)
img_matches1 = cv2.drawMatches(chessboard,chessboard_keyPoint,chessboard2,chessboard2_keyPoint,matches,img_matches)
cv2.imshow('chessboard_orb_matches',img_matches1)
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# Harris角点检测
chessboard = cv2.imread(chessboard_filename)
chessboard2 = cv2.imread(chessboard2_filename)
gray = cv2.cvtColor(chessboard,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(chessboard2,cv2.COLOR_BGR2GRAY)
img = cv2.cornerHarris(gray,2,3,0.04)
img = cv2.dilate(img,None)
img2 = cv2.cornerHarris(gray2,2,3,0.04)

cv2.imshow('test',img2)
img2 = cv2.dilate(img2,None)
chessboard[img>0.01*img.max()] = [0,0,255]
chessboard2[img2>0.01*img2.max()] = [0,255,0]
cv2.imshow('Harris',chessboard)
cv2.imshow('Harris2',chessboard2)
cv2.waitKey()
cv2.destroyAllWindows()


# 人像图
# ======================================================================================================

timg1 = cv2.imread(os.path.abspath('第二次作业/timg.jpg'))
timg2 = cv2.imread(os.path.abspath('第二次作业/timg2.jpg'))
img1,img2 = None,None
# --------------------------------------------------------------------
# surf特征匹配
# 创建surf算子
surf_detector = cv2.xfeatures2d.SURF_create(1000)
# 计算特征点和描述符
timg1_keyPoint,timg1_desc = surf_detector.detectAndCompute(timg1,None)
timg2_keyPoint,timg2_desc = surf_detector.detectAndCompute(timg2,None)
# 画出特征点
img1 = cv2.drawKeypoints(timg1,timg1_keyPoint,img1,color=[0,0,255])
img2 = cv2.drawKeypoints(timg2,timg2_keyPoint,img2,color=[0,255,0])
cv2.imshow('surf1',img1)
cv2.imshow('surf2',img2)
# 描述子匹配
timg_matcher = cv2.DescriptorMatcher_create('BruteForce')
matches = timg_matcher.match(timg1_desc,timg2_desc)
img_matches = np.empty(timg2.shape)
img_matches1 = cv2.drawMatches(timg1,timg1_keyPoint,timg2,timg2_keyPoint,matches,img_matches)
cv2.imshow('timg_surf_matches',img_matches1)
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# FAST角点检测
# 创建fast算子
fast_detector = cv2.FastFeatureDetector_create(30,nonmaxSuppression=True,type = cv2.FAST_FEATURE_DETECTOR_TYPE_9_16)
# 提取角点
timg1_keyPoint = fast_detector.detect(timg1,None)
timg2_keyPoint = fast_detector.detect(timg2,None)
img1 = cv2.drawKeypoints(timg1,timg1_keyPoint,img1,color=[0,0,255])
img2 = cv2.drawKeypoints(timg2,timg2_keyPoint,img2,color=[0,255,0])
cv2.imshow('fast1',img1)
cv2.imshow('fast2',img2)
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# SIFT特征描述
# 创建sift描述符
sift_detector = cv2.xfeatures2d.SIFT_create()
# 计算关键点和描述符
timg1_keyPoint,timg1_desc = sift_detector.detectAndCompute(timg1,None)
timg2_keyPoint,timg2_desc = sift_detector.detectAndCompute(timg2,None)
# 画出关键点
img1 = cv2.drawKeypoints(timg1,timg1_keyPoint,img1,color=[0,0,255])
img2 = cv2.drawKeypoints(timg2,timg2_keyPoint,img2,color=[0,255,0])
cv2.imshow('sift1',img1)
cv2.imshow('sift2',img2)
# 特征匹配
timg_matcher = cv2.DescriptorMatcher_create('BruteForce')
matches = timg_matcher.match(timg1_desc,timg2_desc)
matches = matches[::5]
img_matches = np.empty(timg2.shape)
img_matches1 = cv2.drawMatches(timg1,timg1_keyPoint,timg2,timg2_keyPoint,matches,img_matches)
cv2.imshow('timg_sift_matches',img_matches1)
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# ORB特征描述
# 创建orb算子
orb_detector = cv2.ORB_create(200)
# 角点检测和描述符计算
timg1_keyPoint,timg1_desc = orb_detector.detectAndCompute(timg1,None)
timg2_keyPoint,timg2_desc = orb_detector.detectAndCompute(timg2,None)
# 画出关键点
img1 = cv2.drawKeypoints(timg1,timg1_keyPoint,img1,color=[0,0,255])
img2 = cv2.drawKeypoints(timg2,timg2_keyPoint,img2,color=[0,255,0])
cv2.imshow('orb1',img1)
cv2.imshow('orb2',img2)
# 匹配描述符
timg_matcher = cv2.DescriptorMatcher_create('BruteForce')
matches = timg_matcher.match(timg1_desc,timg2_desc)
matches = matches[::5]
img_matches = np.empty(timg2.shape)
img_matches1 = cv2.drawMatches(timg1,timg1_keyPoint,timg2,timg2_keyPoint,matches,img_matches)
cv2.imshow('timg_orb_matches',img_matches1)
cv2.waitKey()
cv2.destroyAllWindows()

# --------------------------------------------------------------------
# Harris角点检测
# 创建角点检测
gray1 = cv2.cvtColor(timg1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(timg2,cv2.COLOR_BGR2GRAY)
img1 = cv2.cornerHarris(gray1,2,3,0.04)
img1 = cv2.dilate(img1,None)
img2 =cv2.cornerHarris(gray2,2,3,0.04)
img2 = cv2.dilate(img2,None)
timg1[img1>0.01*img1.max()] = [0,0,255]
timg2[img2>0.01*img2.max()] = [0,0,255]
cv2.imshow('harris1',timg1)
cv2.imshow('harris2',timg2)
timg1[img1>0.001*img1.max()] = [0,0,255]
timg2[img2>0.001*img2.max()] = [0,0,255]
cv2.imshow('harris1',timg1)
cv2.imshow('harris2',timg2)

cv2.waitKey()
cv2.destroyAllWindows()

